﻿using log4net;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using RabbitMQ.Client;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ProducerMQ.Models
{
    /// <summary>
    /// 生產者
    /// </summary>
    public class RabbitMQClient
    {
        private readonly IModel _channel;
        private ILog log;
        private readonly string ExchangeName;
        private readonly string QueueName;
        public RabbitMQClient(IOptions<RabbitMQSetting> options)
        {
            this.log = LogManager.GetLogger(Startup.repository.Name, typeof(RabbitMQClient));
            try
            {
                var factory = new ConnectionFactory()
                {
                    HostName = options.Value.RabbitHost,
                    UserName = options.Value.RabbitUserName,
                    Password = options.Value.RabbitPassword,
                    Port = options.Value.RabbitPort,
                    AutomaticRecoveryEnabled = true  //斷線自動恢復
                };
                var connection = factory.CreateConnection();
                this._channel = connection.CreateModel();

                this.ExchangeName = "ExchangeName_GLZ";
                this.QueueName = "QueueName_GLZ";
            }
            catch (Exception ex)
            {
                log.Info(ex);
            }
        }

        /// <summary>
        /// 發送消息
        /// </summary>
        /// <param name="routingKey"></param>
        /// <param name="message"></param>
        public virtual void PushMessage(string routingKey, object message)
        {
            log.Info($"PushMessage,routingKey:{routingKey}");

            _channel.ExchangeDeclare(exchange: ExchangeName, type: "topic");

            _channel.QueueDeclare(queue: QueueName,
                                        durable: true,
                                        exclusive: false,
                                        autoDelete: false,
                                        arguments: null);

            _channel.QueueBind(QueueName, ExchangeName, routingKey);

            _channel.ConfirmSelect();  //启动消息发送确认机制，即需要收到RabbitMQ服务端的确认消息

            var properties = _channel.CreateBasicProperties();
            properties.Persistent = true;
            properties.MessageId = Guid.NewGuid().ToString("N");
            properties.Timestamp = new AmqpTimestamp(DateTimeOffset.UtcNow.ToUnixTimeMilliseconds());
            properties.Headers = new Dictionary<string, object>
            {
                { "retryCount", "3"}
            };
            
            string msgJson = JsonConvert.SerializeObject(message);
            var body = Encoding.UTF8.GetBytes(msgJson);

            _channel.BasicPublish(exchange: ExchangeName,
                                    routingKey: routingKey,
                                    basicProperties: properties,
                                    body: body);

            var isOk = _channel.WaitForConfirms();  //确定收到RabbitMQ服务端的确认消息
            if (!isOk)
            {
                log.Error("The message is not reached to the server!");
            }
            //_channel.Close();
        }

       
    }
}
